package com.duzilin.ehrecyclerview.Wrapper;

import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by DuZiLin on 2018/1/5.
 *
 * 原理为根据不同的ViewType来加载不同的布局
 */

public abstract class RecyclerViewAdapterPlus<T> extends RecyclerView.Adapter{

    private static final int TYPE_HEADER = 1;
    private static final int TYPE_FOOTER = 2;
    private static final int TYPE_NORMAL = 0;

    /**
     * 数据源
     */
    private List<T> data = new ArrayList<>();
    /**
     * 头部view
     */
    private View mHeaderView;
    /**
     * 底部view
     */
    private View mFooterView;
    /**
     * item监听器
     */
    private OnItemClickListener mLinstener;

    public View getHeaderView() {
        return mHeaderView;
    }

    public void setHeaderView(View mHeaderView) {
        this.mHeaderView = mHeaderView;
        //设置头部后，将其放入第一位，后面的item都向后推
        notifyItemInserted(0);
    }

    public View getFooterView() {
        return mFooterView;
    }

    public void setFooterView(View mFooterView) {
        this.mFooterView = mFooterView;
    }

    public void setOnItemClickLinstener(OnItemClickListener mLinstener) {
        this.mLinstener = mLinstener;
    }

    /**
     * itme点击借口
     * @param <T>
     */
    public interface OnItemClickListener<T>{
        void onItemClick(int position , T data);
    }

    /**
     * 添加数据
     * @param datas 需要添加的数据
     */
    public void addDatas(List<T> datas){
        this.data.addAll(datas);
        notifyDataSetChanged();
    }

    /**
     * 添加数据
     * @param data 需要添加的数据
     */
    public void addData(T data){
        this.data.add(data);
        notifyDataSetChanged();
    }

    /**
     * 为Header和Footer设置ViewTyoe
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        if(mHeaderView == null) return TYPE_NORMAL;
        if(position == 0) return TYPE_HEADER;
        if(position == (getItemCount()-1) && mFooterView!= null) return TYPE_FOOTER;
        return TYPE_NORMAL;
    }

    /**
     * 根据不同的viewType创建不同的ViewHolder
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(viewType == TYPE_HEADER&& mHeaderView != null) return new AddViewHolder(mHeaderView);
        if(viewType == TYPE_FOOTER && mFooterView != null) return new AddViewHolder(mFooterView);
        return onCreateItemViewHolder(parent , viewType);
    }

    /**
     * 获取正确的position
     * @param viewHolder
     * @return
     */
    public int getRealPosition(ViewHolder viewHolder){
        int position = viewHolder.getLayoutPosition();
        return mHeaderView == null?position : position-1;
    }

    /**
     * Header和Footer不需要绑定数据直接return
     * 绑定Item数据由用户编码
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        if(getItemViewType(position) == TYPE_HEADER) return;
        if(getItemViewType(position) == TYPE_FOOTER) return;
        final int realPosition = getRealPosition(holder);
        final T itemData = data.get(realPosition);
        onBindItemViewHolder(holder , realPosition , itemData);
        if (mLinstener != null){
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mLinstener.onItemClick(realPosition , itemData);
                }
            });
        }

    }

    /**
     * Header和Footer不为空时需要为itemCount增加
     * @return
     */
    @Override
    public int getItemCount() {
        int itemCount = data.size();
        if(mHeaderView != null) itemCount++;
        if(mFooterView != null) itemCount++;
        return itemCount;
    }

    /**
     * Header和Footer的ViewHolder
     */
    class AddViewHolder extends ViewHolder{
        public AddViewHolder(View itemView) {
            super(itemView);
        }
    }

    /**
     * 若LayoutManager为GridLayoutManager时，Header和Footer需要占多个单元
     * @param recyclerView
     */
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if(layoutManager instanceof GridLayoutManager){
            final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    if(getItemViewType(position) == TYPE_HEADER ) return gridLayoutManager.getSpanCount();
                    if(getItemViewType(position) == TYPE_FOOTER ) return gridLayoutManager.getSpanCount();
                    return 1;
                }
            });
        }
    }

    /**
     * 支持瀑布流StaggeredGridLayoutManager
     * @param
     */
    @Override
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        if(lp != null
                && lp instanceof StaggeredGridLayoutManager.LayoutParams) {
            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
            p.setFullSpan(holder.getLayoutPosition() == 0);
        }
    }

    /**
     * 需要用户编写的ItemViewHolder
     * @param parent
     * @param viewType
     * @return
     */
    public abstract ViewHolder onCreateItemViewHolder(ViewGroup parent , int viewType);

    /**
     * 需要用户编写的Item绑定数据
     * @param viewHolder
     * @param position
     * @param data
     */
    public abstract void onBindItemViewHolder(ViewHolder viewHolder , int position , T data);







}
